package com.sibu.yx.promotion.admin.web.support.exception;

import com.sibu.yx.promotion.common.enums.ErrorCodeEnum;
import com.sibu.yx.promotion.common.manage.ResponseManage;
import com.sibu.yx.promotion.service.exception.DataBaseException;
import org.apache.shiro.authz.UnauthenticatedException;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.doubo.common.exception.SystemException;
import com.doubo.common.model.response.CommonResponse;
import com.doubo.common.threadlocal.SerialNo;
import com.doubo.common.util.ExceptionUtil;

import lombok.extern.slf4j.Slf4j;
/**
 * User: qiujingwang
 * Date: 2016/3/17
 * Time: 16:16 异常处理
 */
@ControllerAdvice
@Slf4j
@Component
public class WebExceptionHandler {

    /**
     * 当前系统自定义异常，应该抛出前记录日志，故这里不需要记录
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(SystemException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleSystemException(SystemException ex) {
        CommonResponse response = ResponseManage.fail(ex);
        return response;
    }

    /**
     * 参数验证、绑定异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(BindException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleBindException(BindException ex) {
        CommonResponse response = ResponseManage.fail(ex);
        log.error("[{}] Validate error msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), response.getErrorMsg(), ex.getFieldError());
        return response;
    }

    /**
     * 参数验证、绑定异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleValidateException(MethodArgumentNotValidException ex) {
        CommonResponse response = ResponseManage.fail(ex.getBindingResult());
        log.error("[{}] Validate error msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), response.getErrorMsg(), ex.getBindingResult().getFieldError());
        return response;
    }

    /**
     * 当前系统自定义异常，应该抛出前记录日志，故这里不需要记录
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(DataBaseException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleSystemException(DataBaseException ex) {
        CommonResponse response = ResponseManage.fail(ex.getMessage());
        log.error("[{}] System Exception msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), ex.getMessage(), ExceptionUtil.getAsString(ex));
        return response;
    }

    /**
     * 未登录
     * @param ex
     * @return
     */
    @ExceptionHandler(UnauthenticatedException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleAllException(UnauthenticatedException ex) {
        log.error("[{}] Account UnauthenticatedException msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), ex.getMessage(),
                ExceptionUtil.getAsString(ex));
        return ResponseManage.fail(ErrorCodeEnum.SESSION_TIMEOUT);
    }

    /**
     * 无权限
     * @param ex
     * @return
     */
    @ExceptionHandler(UnauthorizedException.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleAllException(UnauthorizedException ex) {
        log.error("[{}] Account UnauthenticatedException msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), ex.getMessage(), ExceptionUtil.getAsString(ex));
        return ResponseManage.fail("无操作权限");
    }

    /**
     * 系统异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    @ResponseStatus(value = HttpStatus.OK)
    public CommonResponse handleAllException(Throwable ex) {
        if ("org.apache.catalina.connector.ClientAbortException".equals(ex.getClass().getName())) {
            // 客户关掉了浏览器引起异常，简单记录
            log.error("[{}] System Error msg[{}] ClientAbortException", SerialNo.getSerialNo(), ex.getMessage());
        } else if ("org.springframework.web.HttpRequestMethodNotSupportedException".equals(ex.getClass().getName())) {
            return ResponseManage.fail(ex.getMessage() + ",只支持[get,post]");
        } else if ("com.fdfs.pool.exception.FdfsException".equals(ex.getClass().getName())) {
            log.error("[{}] System Error msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), ex.getMessage(), ExceptionUtil.getAsString(ex));
            return ResponseManage.fail("图片存储服务出错,请稍后重试!");
        } else if ("org.springframework.web.servlet.NoHandlerFoundException".equals(ex.getClass().getName())) {
            return ResponseManage.fail("接口路径不存在");
        } else {
            log.error("[{}] System Error msg[{}].\nSome Exception Occur:[{}]", SerialNo.getSerialNo(), ex.getMessage(), ExceptionUtil.getAsString(ex));
        }
        return ResponseManage.fail("系统异常");
    }
}
